<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="https://unpkg.com/vue@2"></script>
</head>
<body>
  <div id="app">
    <h1 class="title">{{ message }}</h1>
    <p class="content" v-size-ob="handleResize">被监听的盒子</p>
    <table class="info">
      <tr>
        <td style="width: 40px">width: </td>
        <td>{{pWidth}}px</td>
      </tr>
      <tr>
        <td>height: </td>
        <td>{{pHeight}}px</td>
      </tr>
    </table>
  </div>
</body>
<style>
  .title {
    border-bottom: 1px solid #eee;
    padding: 20px 0;
  }
  .content{
    border: 1px solid #bbb;
    background: #f5f5f5;
    padding: 10px;
  }
  .info {
    font-size: 12px;
    color: #666;
  }
</style>
<script>
  /**
   * 封装v-size-ob指令，监听元素尺寸变化，返回宽高信息
   */ 
  const map = new WeakMap()
  const ob = new ResizeObserver((entires) => {
    for(const entry of entires) {
      // 运行 entry.target 对应的回调函数
      const handler = map.get(entry.target)
      const { inlineSize, blockSize } = entry.borderBoxSize[0]
      if (handler) {
        handler({ width: inlineSize, height: blockSize })
      }
    }
  })

  Vue.directive('size-ob', {
    bind(el, binding, vnode) {
      // 监听el尺寸变化
      ob.observe(el)
      map.set(el, binding.value);
    },
    unbind(el) {
      // 取消监听
      ob.unobserve(el)
    },
  })
  new Vue({
    el: '#app',
    data() {
      return {
        message: '监听元素尺寸变化的指令',
        pWidth: 0,
        pHeight: 0,
      }
    },
    methods:{
      handleResize(size) {
        this.pWidth = size.width
        this.pHeight = size.height
      }
    }
  })
</script>
</html>
